package com.pai4j.message.core.provider;

import lombok.extern.slf4j.Slf4j;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 资源提供者注册中心
 * 管理所有ResourceProvider的注册和查找
 * 
 * 采用单例模式，线程安全
 *
 * @author PAI4J Team
 * @date 2025-11-01
 */
@Slf4j
public class ResourceRegistry {

    /**
     * 资源提供者映射表
     * key: 资源类型（如ARTICLE、MOMENT等）
     * value: 资源提供者列表（按优先级排序）
     */
    private static final Map<String, List<ResourceProvider>> PROVIDER_MAP = new ConcurrentHashMap<>();

    /**
     * 所有注册的提供者列表
     */
    private static final Map<String, ResourceProvider> ALL_PROVIDERS = new ConcurrentHashMap<>();

    /**
     * 注册资源提供者
     * 
     * @param provider 资源提供者
     */
    public static synchronized void register(ResourceProvider provider) {
        if (provider == null) {
            log.warn("尝试注册null ResourceProvider");
            return;
        }

        String resourceType = provider.getResourceType();
        if (resourceType == null || resourceType.trim().isEmpty()) {
            log.warn("ResourceProvider的resourceType不能为空: {}", provider.getClass().getName());
            return;
        }

        // 生成唯一标识
        String providerId = provider.getClass().getName();
        
        // 检查是否已注册
        if (ALL_PROVIDERS.containsKey(providerId)) {
            log.debug("ResourceProvider已注册，跳过: {} for {}", providerId, resourceType);
            return;
        }

        // 添加到全局列表
        ALL_PROVIDERS.put(providerId, provider);

        // 添加到类型映射表
        PROVIDER_MAP.compute(resourceType.toUpperCase(), (k, providers) -> {
            if (providers == null) {
                providers = new java.util.ArrayList<>();
            }
            providers.add(provider);
            // 按优先级排序（数字越小优先级越高）
            providers.sort(Comparator.comparingInt(ResourceProvider::getPriority));
            return providers;
        });

        log.info("注册ResourceProvider成功: {} for {} (priority: {})", 
                providerId, resourceType, provider.getPriority());
    }

    /**
     * 获取指定类型的资源提供者（优先级最高的）
     * 
     * @param resourceType 资源类型
     * @return 资源提供者，未找到返回null
     */
    public static ResourceProvider getProvider(String resourceType) {
        if (resourceType == null || resourceType.trim().isEmpty()) {
            return null;
        }

        List<ResourceProvider> providers = PROVIDER_MAP.get(resourceType.toUpperCase());
        if (providers != null && !providers.isEmpty()) {
            return providers.get(0); // 返回优先级最高的
        }
        
        return null;
    }

    /**
     * 获取指定类型的所有资源提供者
     * 
     * @param resourceType 资源类型
     * @return 资源提供者列表（按优先级排序）
     */
    public static List<ResourceProvider> getProviders(String resourceType) {
        if (resourceType == null || resourceType.trim().isEmpty()) {
            return java.util.Collections.emptyList();
        }

        List<ResourceProvider> providers = PROVIDER_MAP.get(resourceType.toUpperCase());
        return providers != null ? new java.util.ArrayList<>(providers) : java.util.Collections.emptyList();
    }

    /**
     * 判断是否支持指定的资源类型
     * 
     * @param resourceType 资源类型
     * @return 是否支持
     */
    public static boolean supports(String resourceType) {
        return getProvider(resourceType) != null;
    }

    /**
     * 获取所有已注册的资源类型
     * 
     * @return 资源类型列表
     */
    public static List<String> getAllResourceTypes() {
        return PROVIDER_MAP.keySet().stream()
                .sorted()
                .collect(Collectors.toList());
    }

    /**
     * 获取所有已注册的提供者
     * 
     * @return 提供者列表
     */
    public static List<ResourceProvider> getAllProviders() {
        return new java.util.ArrayList<>(ALL_PROVIDERS.values());
    }

    /**
     * 取消注册资源提供者
     * 
     * @param provider 资源提供者
     */
    public static synchronized void unregister(ResourceProvider provider) {
        if (provider == null) {
            return;
        }

        String providerId = provider.getClass().getName();
        ALL_PROVIDERS.remove(providerId);

        String resourceType = provider.getResourceType();
        if (resourceType != null) {
            PROVIDER_MAP.computeIfPresent(resourceType.toUpperCase(), (k, providers) -> {
                providers.removeIf(p -> p.getClass().getName().equals(providerId));
                return providers.isEmpty() ? null : providers;
            });
            log.info("取消注册ResourceProvider: {} for {}", providerId, resourceType);
        }
    }

    /**
     * 清空所有注册
     */
    public static synchronized void clear() {
        ALL_PROVIDERS.clear();
        PROVIDER_MAP.clear();
        log.info("清空所有ResourceProvider注册");
    }

    /**
     * 获取注册统计信息
     */
    public static String getRegistryInfo() {
        StringBuilder info = new StringBuilder("ResourceRegistry Info:\n");
        info.append("Total Providers: ").append(ALL_PROVIDERS.size()).append("\n");
        info.append("Supported Resource Types: ").append(PROVIDER_MAP.size()).append("\n");
        for (Map.Entry<String, List<ResourceProvider>> entry : PROVIDER_MAP.entrySet()) {
            info.append("  - ").append(entry.getKey()).append(": ")
                .append(entry.getValue().size()).append(" provider(s)\n");
        }
        return info.toString();
    }
}

